import java.util.ArrayList;
import java.util.Arrays;


public class TSP {
	double[][] pos;
	int[] solution;
	int n;
	Node sol_start;
	long start_time = System.currentTimeMillis();
	long time_limit = 1800;
	//boolean use_time_limits = false;
	boolean use_time_limits = true;
	
	SatelliteList satellite;
	
	public static void main(String[] args) {
		new TSP();
	}
	
	public TSP(){
		Kattio io = new Kattio(System.in, System.out);
		n = io.getInt();
		pos = new double[n][2];
		solution = new int[n];
		
		for(int i=0;i<n;i++){
			pos[i][0] = io.getDouble();
			pos[i][1] = io.getDouble();
		}
		
		solve();
		
		solution[0] = sol_start.i;
		Node node = sol_start.getNext();
		
		int solution_index = 1;
		while(node != sol_start){
			solution[solution_index] = node.i;
			node = node.getNext();
			solution_index++;
		}
		
		/*
		for(int i : solution){
			io.println(i);
		}
		
		new TSPDrawer(pos, solution, 5, solution_index);
		*/
		
		//new TSPDrawer(pos, satellite.solution(n), 5, solution_index);
		
		for(int i : satellite.solution(n)){
			io.println(i);
		}
		
		//testcode
		/*
		double sum = 0;
		for(int i=0;i<n;i++){
			sum += dist(solution.get(i)[0],solution.get((i+1) % n)[0]);
		}
		System.err.println("sum = "+sum);*/
		//sum = 323.0
		//sum = 315.0
		
		io.flush();
		io.close();
	}
	
	public void solve(){
		NN();
		satellite = new SatelliteList(n, sol_start);
		twoOPT2();
	}
	
	public void NN(){
		boolean[] visited = new boolean[n];
		
		visited[0]=true;
		sol_start = new Node(0);
		Node current = sol_start;
		
		for(int sol_size=1;sol_size<n;sol_size++){
			double min=Double.MAX_VALUE;
			int min_i=-1;
			
			for(int i=0;i<n;i++){
				if(i!= current.i && visited[i]==false){
					double dist = dist(current.i,i);
					
					if(dist < min){
						min = dist;
						min_i = i;
					}
				}
			}
			
			visited[min_i]=true;
			
			Node n = new Node(min_i);
			n.setPrev(current);
			current.setNext(n);

			current = current.getNext();
		}
		current.setNext(sol_start);
		sol_start.setPrev(current);
	}
	
	public void twoOPT(){
		
		int steps_since_last_improvement = 0;
		Node n1 = sol_start.getNext();
		//while(n1 != sol_start){
		while(steps_since_last_improvement < n*n){
			Node n2 = sol_start.getNext();
			if(System.currentTimeMillis() - start_time > time_limit && use_time_limits){
				return;
			}
			
			while(n2 != sol_start){
				if(System.currentTimeMillis() - start_time > time_limit && use_time_limits){
					return;
				}
				if(n1 != n2){
					double old_d1 = dist(n1.i, n1.getNext().i);
					double old_d2 = dist(n2.i, n2.getNext().i);
					double new_d1 = dist(n1.i, n2.i);
					double new_d2 = dist(n1.getNext().i, n2.getNext().i);
					
					if(new_d1+new_d2 < old_d1+old_d2){
						steps_since_last_improvement = 0;
						//System.err.println("swapping n1="+n1.i+", n1.next ="+n1.getNext().i+ " n2="+n2.i+", n2.next ="+n2.getNext().i);
						swap(n1, n2);
					}
					else{
						steps_since_last_improvement++;
					}
				}
				n2 = n2.getNext();
			}
			n1 = n1.getNext();
		}
	}
	
	public void twoOPT2(){
		
		if(n == 1) return;
		
		int steps_since_last_improvement = 0;
		int n1 = satellite.getNextNode(0);
		while(steps_since_last_improvement < n*n){
			int  n2 = satellite.getNextNode(0);
			if(System.currentTimeMillis() - start_time > time_limit && use_time_limits){
				return;
			}
			
			while(satellite.getNodeNr(n2) != 0){
				
				if(System.currentTimeMillis() - start_time > time_limit && use_time_limits){
					return;
				}
				if(satellite.getNodeNr(n1) != satellite.getNodeNr(n2)){
					
					double old_d1 = dist(satellite.getNodeNr(n1), satellite.getNextNodeNr(n1));
					double old_d2 = dist(satellite.getNodeNr(n2), satellite.getNextNodeNr(n2));
					double new_d1 = dist(satellite.getNodeNr(n1), satellite.getNodeNr(n2));
					double new_d2 = dist(satellite.getNextNodeNr(n1), satellite.getNextNodeNr(n2));
					
					if(new_d1+new_d2 < old_d1+old_d2){
						steps_since_last_improvement = 0;
						//System.err.println("swapping n1="+satellite.getNodeNr(n1)+", n1.next ="+satellite.getNextNodeNr(n1)+ " n2="+satellite.getNodeNr(n2)+", n2.next ="+satellite.getNextNodeNr(n2));
						swap2(n1, n2);
						//satellite.testSwap(n);
						//satellite.print();
						n2 = satellite.getNextNode(0);
						n1 = satellite.getNextNode(0);
					}
					else{
						steps_since_last_improvement++;
					}
				}
				n2 = satellite.getNextNode(n2);
			}
			n1 = satellite.getNextNode(n1);
		}

	}
	
	public void swap(Node n1, Node n2){
		Node temp = n1.getNext();
		Node temp2 = n2.getNext();
		
		n1.setNext(n2);
		n2.setNext(n1);// setPrev = n1 but the loop changes dir :/
		
		Node n = n2;
		while(n != temp){
			n.forward = !n.forward;
			n = n.getNext();
		}
		temp.forward = !temp.forward;
		
		temp.setNext(temp2);
		temp2.setPrev(temp);
	}
	
	public void swap2(int n1, int n2){
		int t1 = satellite.getNextNode(n1);
		int t2 = satellite.getNextNode(n2);
		
		//System.out.println("n1: " + n1 + " n2: " + n2);
		//System.out.println("t1: " + t1 + " t2: " + t2);
		
		satellite.setNextNode(n2, n1^1);
		satellite.setNextNode(n1, n2^1);
		satellite.setNextNode(t1^1, t2);
		satellite.setNextNode(t2^1, t1);
	}
	
	public double dist(int i, int j){
		double x= pos[i][0] - pos[j][0];
		double y= pos[i][1] - pos[j][1];
		
		return Math.round(Math.sqrt(x*x+y*y));
	}
	
}


class SatelliteList{
	private int[] satelliteArray;
	
	public SatelliteList(int n){
		satelliteArray = new int[2*n];
	}
	
	public SatelliteList(int n, Node sol_start){
		satelliteArray = new int[2*n];

		satelliteArray[sol_start.i*2] = sol_start.getNext().i*2;
		satelliteArray[sol_start.i*2 + 1] = sol_start.getPrev().i*2+1;
		Node node = sol_start.getNext();
		while(node != sol_start){
			satelliteArray[node.i*2] = node.getNext().i*2;
			satelliteArray[node.i*2 + 1] = node.getPrev().i*2+1;
			node = node.getNext();
		}
	}
	
	public int getNextNode(int i){
		return satelliteArray[i];
	}
	
	public void setNextNode(int i, int x){
		satelliteArray[i] = x;
	}
	
	public int getNodeNr(int i){
		if(i % 2 == 0)
			return i/2;
		else
			return (i-1)/2;
	}
	
	public int getNextNodeNr(int i){
		if(satelliteArray[i] % 2 == 0)
			return satelliteArray[i]/2;
		else
			return (satelliteArray[i]-1)/2;
	}
	
	public void print(){
		System.out.println(Arrays.toString(satelliteArray));
	}
	
	public int[] solution(int n){
		int[] s = new int[n];
		int c = 0;
		int i = 1;
		int node = 0;
		s[0] = node;
		while(getNextNode(node) != 0){
			s[i] = getNextNodeNr(node);
			node = getNextNode(node);
			i++;
		}
	return s;	
	}
	
	public void testSwap(int n){
		int i = 1;
		int node = 0;
		System.out.print(node + " ");
		while(getNextNode(node) != 0 && i < 2*n){
			node = getNextNode(node);
			System.out.print(node + " ");
			i = i+1;
		}
		System.out.println();
		if (i > n || i < n) System.out.println("SWAP FAIL! " + i + " " + n);
		else System.out.println("OK!");
		
		i = 1;
		node = 1;
		System.out.print(node + " ");
		while(getNextNode(node) != 1 && i < 2*n){
			node = getNextNode(node);
			System.out.print(node + " ");
			i = i+1;
		}
		System.out.println();
		if (i > n || i < n) System.out.println("Reverse SWAP FAIL! " + i + " " + n);
		else System.out.println("Reverse OK!");
		
	}
	
}

class Node{
	private Node next;
	private Node prev;
	int i;
	boolean forward;
	public Node(int i){
		this.i=i;
		forward = true;
	}
	
	public Node getNext(){
		return forward ? next : prev;
	}
	public void setNext(Node n){
		if(forward) next = n;
		else prev = n;
	}
	
	public Node getPrev(){
		return !forward ? next : prev;
	}
	public void setPrev(Node n){
		if(!forward) next = n;
		else prev = n;
	}
}
























